home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / examples / demo / demosrc / d_imagproc.pro < prev    next >
Text File  |  1997-07-08  |  66KB  |  1,826 lines

  1. ; $Id: d_imagproc.pro,v 1.17 1997/04/18 22:43:17 tremblay Exp $
  2. ;
  3. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;
  6. ;+
  7. ;  FILE:
  8. ;       d_imagproc.pro
  9. ;
  10. ;  CALLING SEQUENCE: d_imagproc
  11. ;
  12. ;  PURPOSE:
  13. ;       Displays six different aspects of image processing: 
  14. ;       Fourier filtering, pixel scaling, pixel distribution
  15. ;       (histogram), edge enhancement, convolution, and
  16. ;       zooming.
  17. ;
  18. ;  MAJOR TOPICS: Image processing and widgets
  19. ;
  20. ;  CATEGORY:
  21. ;       IDL 5.0
  22. ;
  23. ;  INTERNAL FUNCTIONS and PROCEDURES:
  24. ;       pro ipr_makezooming         - Zoom a portion of an image
  25. ;       pro ipr_makeFilter          - Applied fourier filtering 
  26. ;       pro ipr_doFilterSlider      - Set the filter parameter with the slider
  27. ;       pro ipr_makeScaling         - Scale an image
  28. ;       pro ipr_makeHistogram       - Create data for the histogram
  29. ;       pro ipr_DrawHistogram       - Plot a histogram
  30. ;       pro ipr_makeEdge            - Compute edging enhancement
  31. ;       pro ipr_drawEdge            - Draw the edge enhanced image
  32. ;       pro ipr_makeConvolution     - Apply convolution on an image
  33. ;       pro ipr_drawConvolution     - Draw the convoluted image
  34. ;       pro ipr_drawGrid            - Draw the kernel grid
  35. ;       pro d_imagproc_Event      - Event handler
  36. ;       pro d_imagprocCleanup     - Cleanup
  37. ;       pro d_imagproc            - Main procedure
  38. ;
  39. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  40. ;       pro gettips             - Read tip file
  41. ;       pro widtips             - Create widget text to dsplay tips.
  42. ;       pro sizetips            - Size the tip widgets.
  43. ;       pro puttips             - Change the tips text.
  44. ;       imagproc.txt
  45. ;       imagproc.tip
  46. ;       nyny.dat
  47. ;
  48. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  49. ;
  50. ;  NAMED STRUCTURES:
  51. ;       none.
  52. ;
  53. ;  COMMON BLOCS:
  54. ;       none.
  55. ;
  56. ;  MODIFICATION HISTORY:  Written by:  DC, RSI,  1995
  57. ;                         Modified by DAT,RSI,  December 1996
  58. ;                         Combining tour elements 203, 280 to 284
  59. ;-
  60. ;--------------------------------------------------------------------
  61.  
  62.  
  63. ; Copyright (c) 1995, Research Systems, Inc.  All rights reserved.
  64. ;       Unauthorized reproduction prohibited.
  65. ;
  66. ;+
  67. ; NAME:
  68. ;       LPF_ALL
  69. ;
  70. ; PURPOSE:
  71. ;       This function performs Low Pass Filtering (smoothing) on one,
  72. ;       two, and three dimensional arrays.   This function is similar
  73. ;       to the "Smooth" function except that it smoothes ALL the array
  74. ;       elements (even at the edges of the array).   The "Smooth" function
  75. ;       does NOT smooth array elements that are within band/2 of any edge
  76. ;       of the array (where band is the width of the smoothing window).
  77. ;       When smoothing a two dimensional array, Lpf_All can optionally
  78. ;       smooth in one of three ways : rectangular, cylindrical, and
  79. ;       spherical.   When smoothing a one dimensional array, Lpf_All
  80. ;       can smooth in either linear or circular mode.
  81. ;
  82. ; CATEGORY:
  83. ;       Filtering.
  84. ;
  85. ; CALLING SEQUENCE:
  86. ;       lpf_array = LPF_ALL(Array, Band)
  87. ;
  88. ; INPUTS:
  89. ;       Array:      The array to smooth.
  90. ;                   Data type : Any one, two, or three dimensional array
  91. ;                   except string or structure.
  92. ;       Band:       The width of the smoothing window.
  93. ;                   Data type : Int
  94. ;
  95. ; KEYWORD PARAMETERS:
  96. ;       Wrap_Mode:  The smoothing mode.   If Array has three dimensions,
  97. ;                   then Wrap_Mode is ignored.   If Array has two dimensions,
  98. ;                   then specify Wrap_Mode=0 for rectangular smoothing,
  99. ;                   Wrap_Mode=1 for cylindrical smoothing, and Wrap_Mode=2
  100. ;                   for spherical smoothing.   In the cylindrical and
  101. ;                   spherical cases, smoothing is performed across the first
  102. ;                   and last columns of Array.   In the spherical case,
  103. ;                   smoothing is also performed across all the elements in the
  104. ;                   top row, and across all the elements in the bottom row.
  105. ;                   If Array has one dimension, then specify Wrap_Mode=0 for
  106. ;                   linear smoothing, and Wrap_mode=1 for circular smoothing.
  107. ;                   In the circular case, smoothing is performed across the
  108. ;                   first and last elements in Array.   The default is zero.
  109. ;
  110. ; OUTPUTS:
  111. ;       Lpf_Array:  The low pass filtered array.
  112. ;                   Data type : Same as input Array.
  113. ;
  114. ; PROCEDURE :
  115. ;       This function smoothes the edges of the array by extrapolating the
  116. ;       values at the edges of the array to a distance of band/2.
  117. ;
  118. ; EXAMPLE:
  119. ;       Smooth a two dimensional array in spherical mode.
  120. ;
  121. ;          ; *** Create data to smooth.
  122. ;          array = REBIN(RANDOMU(s, 8, 8), 512, 512)
  123. ;          ; *** Smooth the array in spherical mode.
  124. ;          lpf_array = LPF_ALL(array, 64, Wrap_Mode=2)
  125. ;
  126. ; MODIFICATION HISTORY:
  127. ;       Written by:     Daniel Carr. Mon Aug 23 12:46:31 MDT 1993
  128. ;-
  129.  
  130. FUNCTION LPF_ALL, array, band, Wrap_Mode=wrap_mode
  131.  
  132. lpf_band = LONG(band(0))
  133.  
  134. IF (N_Elements(wrap_mode) LE 0L) THEN wrap_mode = 0
  135.  
  136. size_arr = SIZE(array)
  137.  
  138. CASE (size_arr(0)) OF
  139.    1L: BEGIN ; *** One dimensional array.
  140.       lpf_array = array
  141.       arr_x = size_arr(1)
  142.       arr_xm1 = arr_x - 1L
  143.       lpf_band = lpf_band < (size_arr(1) - 1L)
  144.  
  145.       wide = lpf_band / 2L
  146.       wide2 = wide * 2L
  147.       wide3 = wide * 3L
  148.       widep1 = wide + 1L
  149.       widem1 = wide - 1L
  150.       wide2p1 = wide2 + 1L
  151.       wide2m1 = wide2 - 1L
  152.       wide3p1 = wide3 + 1L
  153.       wide3m1 = wide3 - 1L
  154.  
  155.       wrap_mode = (wrap_mode > 0) < 1
  156.       CASE (wrap_mode) OF
  157.          0: BEGIN ; *** Regular (linear) smoothing.
  158.             IF (lpf_band GE 2L) THEN BEGIN
  159.                edge_l = Fltarr(wide3, /Nozero)
  160.                edge_r = Fltarr(wide3, /Nozero)
  161.  
  162.                edge_l(0:widem1) = lpf_array(0)
  163.                edge_l(wide:*) = lpf_array(0:wide2m1)
  164.  
  165.                edge_r(0:wide2m1) = lpf_array((arr_x-wide2):*)
  166.                edge_r(wide2:*) = lpf_array(arr_xm1)
  167.  
  168.                edge_l = (SMOOTH(edge_l, lpf_band))(wide:wide2m1)
  169.                edge_r = (SMOOTH(edge_r, lpf_band))(wide:wide2m1)
  170.  
  171.                lpf_array = SMOOTH(lpf_array, lpf_band)
  172.  
  173.                lpf_array(0:widem1) = Temporary(edge_l)
  174.                lpf_array((arr_x-wide):*) = Temporary(edge_r)
  175.             ENDIF
  176.          END
  177.  
  178.          1: BEGIN ; *** Circular smoothing.
  179.             IF (lpf_band GE 2L) THEN BEGIN
  180.                edge_l = Fltarr(wide3, /Nozero)
  181.                edge_r = Fltarr(wide3, /Nozero)
  182.  
  183.                edge_l(0:widem1) = lpf_array((arr_x-wide):*)
  184.                edge_l(wide:*) = lpf_array(0:wide2m1)
  185.  
  186.                edge_r(0:wide2m1) = lpf_array((arr_x-wide2):*)
  187.                edge_r(wide2:*) = lpf_array(0:widem1)
  188.  
  189.                edge_l = (SMOOTH(edge_l, lpf_band))(wide:wide2m1)
  190.                edge_r = (SMOOTH(edge_r, lpf_band))(wide:wide2m1)
  191.  
  192.                lpf_array = SMOOTH(lpf_array, lpf_band)
  193.  
  194.                lpf_array(0:widem1) = Temporary(edge_l)
  195.                lpf_array((arr_x-wide):*) = Temporary(edge_r)
  196.             ENDIF
  197.          END
  198.       ENDCASE
  199.    END
  200.  
  201.    2L: BEGIN ; *** Two dimensional array.
  202.       lpf_array = array
  203.       arr_x = size_arr(1)
  204.       arr_y = size_arr(2)
  205.       arr_xm1 = arr_x - 1L
  206.       arr_ym1 = arr_y - 1L
  207.       lpf_band = lpf_band < (MIN(size_arr(1:2)) - 1L)
  208.       f_arr_x = FLOAT(arr_x)
  209.  
  210.       wide = lpf_band / 2L
  211.       wide2 = wide * 2L
  212.       wide3 = wide * 3L
  213.       widep1 = wide + 1L
  214.       widem1 = wide - 1L
  215.       wide2p1 = wide2 + 1L
  216.       wide2m1 = wide2 - 1L
  217.       wide3p1 = wide3 + 1L
  218.       wide3m1 = wide3 - 1L
  219.       rep_wide = Replicate(1.0, (wide>1L))
  220.  
  221.       wrap_mode = (wrap_mode > 0) < 2
  222.       CASE (wrap_mode) OF
  223.          0: BEGIN ; *** Regular (rectangular) smoothing.
  224.             IF (lpf_band GE 2L) THEN BEGIN
  225.                edge_l = Fltarr(wide3, (arr_y + wide2), /Nozero)
  226.                edge_r = Fltarr(wide3, (arr_y + wide2), /Nozero)
  227.                edge_b = Fltarr(arr_x, wide3, /Nozero)
  228.                edge_t = Fltarr(arr_x, wide3, /Nozero)
  229.  
  230.                edge_l(0:widem1, wide:arr_y+widem1) = rep_wide # lpf_array(0, *)
  231.                edge_l(wide:*, wide:arr_y+widem1) = lpf_array(0:wide2m1, *)
  232.                edge_l(*, 0:widem1) = edge_l(*, wide) # rep_wide
  233.                edge_l(*, arr_y+wide:*) = edge_l(*, arr_y+widem1) # rep_wide
  234.  
  235.                edge_r(0:wide2m1, wide:arr_y+widem1) = $
  236.                   lpf_array(arr_x-wide2:*, *)
  237.                edge_r(wide2:*, wide:arr_y+widem1) = $
  238.                   rep_wide # lpf_array(arr_xm1, *)
  239.                edge_r(*, 0:widem1) = edge_r(*, wide) # rep_wide
  240.                edge_r(*, arr_y+wide:*) = edge_r(*, arr_y+widem1) # rep_wide
  241.  
  242.                edge_b(*, wide:wide3m1) = lpf_array(*, 0:wide2m1)
  243.                edge_b(*, 0:widem1) = edge_b(*, wide) # rep_wide
  244.  
  245.                edge_t(*, 0:wide2m1) = lpf_array(*, arr_y-wide2:*)
  246.                edge_t(*, wide2:*) = edge_t(*, wide2m1) # rep_wide
  247.  
  248.                edge_l = (SMOOTH(edge_l, lpf_band))( $
  249.                                 wide:wide2m1, wide:arr_y+widem1)
  250.                edge_r = (SMOOTH(edge_r, lpf_band))( $
  251.                                 wide:wide2m1, wide:arr_y+widem1)
  252.                edge_b = (SMOOTH(edge_b, lpf_band))( $
  253.                                 wide:arr_x-widep1, wide:wide2m1)
  254.                edge_t = (SMOOTH(edge_t, lpf_band))( $
  255.                                 wide:arr_x-widep1, wide:wide2m1)
  256.  
  257.                lpf_array = SMOOTH(lpf_array, lpf_band)
  258.  
  259.                lpf_array(0:widem1, *) = Temporary(edge_l)
  260.                lpf_array(arr_x-wide:*, *) = Temporary(edge_r)
  261.                lpf_array(wide:arr_x-widep1, 0:widem1) = Temporary(edge_b)
  262.                lpf_array(wide:arr_x-widep1, arr_y-wide:*) = Temporary(edge_t)
  263.             ENDIF
  264.          END
  265.  
  266.          1: BEGIN ; *** Cylindrical smoothing.
  267.             col_array1 = (lpf_array(0, *) + lpf_array(1, *) + $
  268.                           lpf_array(arr_xm1, *)) / 3.0
  269.             col_array2 = (lpf_array(0, *) + lpf_array(arr_xm1-1L, *) + $
  270.                           lpf_array(arr_xm1, *)) / 3.0
  271.             lpf_array(0, *) = Temporary(col_array1)
  272.             lpf_array(arr_xm1, *) = Temporary(col_array2)
  273.  
  274.             IF (lpf_band GE 2) THEN BEGIN
  275.                edge_l = Fltarr(wide3, (arr_y + wide2), /Nozero)
  276.                edge_r = Fltarr(wide3, (arr_y + wide2), /Nozero)
  277.                edge_b = Fltarr(arr_x, wide3, /Nozero)
  278.                edge_t = Fltarr(arr_x, wide3, /Nozero)
  279.  
  280.                edge_l(0:widem1, wide:arr_y+widem1) = lpf_array(arr_x-wide:*, *)
  281.                edge_l(wide:*, wide:arr_y+widem1) = lpf_array(0:wide2m1, *)
  282.                edge_l(*, 0:widem1) = edge_l(*, wide) # rep_wide
  283.                edge_l(*, arr_y+wide:*) = edge_l(*, arr_y+widem1) # rep_wide
  284.  
  285.                edge_r(0:wide2m1, wide:arr_y+widem1) = $
  286.                   lpf_array(arr_x-wide2:*, *)
  287.                edge_r(wide2:*, wide:arr_y+widem1) = $
  288.                   lpf_array(0:widem1, *)
  289.                edge_r(*, 0:widem1) = edge_r(*, wide) # rep_wide
  290.                edge_r(*, arr_y+wide:*) = edge_r(*, arr_y+widem1) # rep_wide
  291.  
  292.                edge_b(*, wide:wide3m1) = lpf_array(*, 0:wide2m1)
  293.                edge_b(*, 0:widem1) = edge_b(*, wide) # rep_wide
  294.  
  295.                edge_t(*, 0:wide2m1) = lpf_array(*, arr_y-wide2:*)
  296.                edge_t(*, wide2:*) = edge_t(*, wide2m1) # rep_wide
  297.  
  298.                edge_l = (SMOOTH(edge_l, lpf_band))( $
  299.                                 wide:wide2m1, wide:arr_y+widem1)
  300.                edge_r = (SMOOTH(edge_r, lpf_band))( $
  301.                                 wide:wide2m1, wide:arr_y+widem1)
  302.                edge_b = (SMOOTH(edge_b, lpf_band))( $
  303.                                 wide:arr_x-widep1, wide:wide2m1)
  304.                edge_t = (SMOOTH(edge_t, lpf_band))( $
  305.                                 wide:arr_x-widep1, wide:wide2m1)
  306.  
  307.                lpf_array = SMOOTH(lpf_array, lpf_band)
  308.  
  309.                lpf_array(0:widem1, *) = Temporary(edge_l)
  310.                lpf_array(arr_x-wide:*, *) = Temporary(edge_r)
  311.                lpf_array(wide:arr_x-widep1, 0:widem1) = Temporary(edge_b)
  312.                lpf_array(wide:arr_x-widep1, arr_y-wide:*) = Temporary(edge_t)
  313.  
  314.                col_array = (lpf_array(0, *) + lpf_array(arr_xm1, *)) / 2.0
  315.                lpf_array(0, *) = col_array
  316.                lpf_array(arr_xm1, *) = Temporary(col_array)
  317.             ENDIF
  318.          END
  319.  
  320.          2: BEGIN ; *** Spherical smoothing.
  321.             col_array = (lpf_array(0, *) + lpf_array(arr_xm1, *)) / 2.0
  322.             lpf_array(0, *) = col_array
  323.             lpf_array(arr_xm1, *) = Temporary(col_array)
  324.  
  325.             lpf_array(*, 0) = TOTAL(lpf_array(*, 0)) / f_arr_x
  326.             lpf_array(*, arr_ym1) = TOTAL(lpf_array(*, arr_ym1)) / f_arr_x
  327.  
  328.             xwide = $
  329.                COS((!PI * 2.0 * (Findgen(arr_y) / Float(arr_y-1L))) + !PI) + 1.0
  330.             xwide = ((xwide^(0.5) * f_arr_x) > 1.0)
  331.             xsize = CEIL(f_arr_x / xwide)
  332.             xwide = LONG(xwide)
  333.             xsize = xsize * xwide
  334.  
  335.             arr_xh = arr_x / 2L
  336.             arr_x2 = arr_x * 2L
  337.             arr_xf = arr_x + arr_xh - 1L
  338.             FOR yy=1L, (arr_y-2L) DO BEGIN
  339.                row_arr = SHIFT([REFORM(lpf_array(*, yy)), $
  340.                                 REFORM(lpf_array(*, yy))], arr_xh)
  341.                row_arr = $
  342.                   CONGRID(REBIN(CONGRID(row_arr, xsize(yy), $
  343.                   /Interp, /Minus_One), xwide(yy)), arr_x2, $
  344.                   /Interp, /Minus_One)
  345.                lpf_array(0, yy) = row_arr(arr_xh:arr_xf)
  346.             ENDFOR
  347.             row_arr = 0
  348.  
  349.             xwide = 0
  350.             xsize = 0
  351.  
  352.             col_array1 = (lpf_array(0, *) + lpf_array(1, *) + $
  353.                           lpf_array(arr_xm1, *)) / 3.0
  354.             col_array2 = (lpf_array(0, *) + lpf_array(arr_xm1-1L, *) + $
  355.                           lpf_array(arr_xm1, *)) / 3.0
  356.             lpf_array(0, *) = Temporary(col_array1)
  357.             lpf_array(arr_xm1, *) = Temporary(col_array2)
  358.  
  359.             IF (lpf_band GE 2) THEN BEGIN
  360.                edge_l = Fltarr(wide3, (arr_y + wide2), /Nozero)
  361.                edge_r = Fltarr(wide3, (arr_y + wide2), /Nozero)
  362.                edge_b = Fltarr(arr_x, wide3, /Nozero)
  363.                edge_t = Fltarr(arr_x, wide3, /Nozero)
  364.  
  365.                edge_l(0:widem1, wide:arr_y+widem1) = lpf_array(arr_x-wide:*, *)
  366.                edge_l(wide:*, wide:arr_y+widem1) = lpf_array(0:wide2m1, *)
  367.                edge_l(*, 0:widem1) = edge_l(*, wide) # rep_wide
  368.                edge_l(*, arr_y+wide:*) = edge_l(*, arr_y+widem1) # rep_wide
  369.  
  370.                edge_r(0:wide2m1, wide:arr_y+widem1) = $
  371.                   lpf_array(arr_x-wide2:*, *)
  372.                edge_r(wide2:*, wide:arr_y+widem1) = $
  373.                   lpf_array(0:widem1, *)
  374.                edge_r(*, 0:widem1) = edge_r(*, wide) # rep_wide
  375.                edge_r(*, arr_y+wide:*) = edge_r(*, arr_y+widem1) # rep_wide
  376.  
  377.                edge_b(*, wide:wide3m1) = lpf_array(*, 0:wide2m1)
  378.                edge_b(*, 0:widem1) = edge_b(*, wide) # rep_wide
  379.  
  380.                edge_t(*, 0:wide2m1) = lpf_array(*, arr_y-wide2:*)
  381.                edge_t(*, wide2:*) = edge_t(*, wide2m1) # rep_wide
  382.  
  383.                edge_l = (SMOOTH(edge_l, lpf_band))( $
  384.                                 wide:wide2m1, wide:arr_y+widem1)
  385.                edge_r = (SMOOTH(edge_r, lpf_band))( $
  386.                                 wide:wide2m1, wide:arr_y+widem1)
  387.                edge_b = (SMOOTH(edge_b, lpf_band))( $
  388.                                 wide:arr_x-widep1, wide:wide2m1)
  389.                edge_t = (SMOOTH(edge_t, lpf_band))( $
  390.                                 wide:arr_x-widep1, wide:wide2m1)
  391.  
  392.                lpf_array = SMOOTH(lpf_array, lpf_band)
  393.  
  394.                lpf_array(0:widem1, *) = Temporary(edge_l)
  395.                lpf_array(arr_x-wide:*, *) = Temporary(edge_r)
  396.                lpf_array(wide:arr_x-widep1, 0:widem1) = Temporary(edge_b)
  397.                lpf_array(wide:arr_x-widep1, arr_y-wide:*) = Temporary(edge_t)
  398.  
  399.                col_array = (lpf_array(0, *) + lpf_array(arr_xm1, *)) / 2.0
  400.                lpf_array(0, *) = col_array
  401.                lpf_array(arr_xm1, *) = Temporary(col_array)
  402.             ENDIF
  403.  
  404.             lpf_array(0, 0) = TOTAL(lpf_array(*, 0)) / f_arr_x
  405.             lpf_array(0, arr_ym1) = TOTAL(lpf_array(*, arr_ym1)) / f_arr_x
  406.          END
  407.       ENDCASE
  408.       rep_wide = 0
  409.    END
  410.  
  411.    3L: BEGIN ; *** Three dimensional array.
  412.       IF (lpf_band GE 2) THEN BEGIN
  413.          arr_x = size_arr(1)
  414.          arr_y = size_arr(2)
  415.          arr_z = size_arr(3)
  416.          arr_xm1 = arr_x - 1L
  417.          arr_ym1 = arr_y - 1L
  418.          arr_zm1 = arr_z - 1L
  419.  
  420.          wide = lpf_band / 2L
  421.          wide2 = wide * 2L
  422.          widem1 = wide - 1L
  423.  
  424.          CASE (size_arr(size_arr(0)+1L)) OF
  425.             0: RETURN, lpf_array
  426.             1: lpf_array = $
  427.                   Bytarr((arr_x+wide2), (arr_y+wide2), (arr_z+wide2), /Nozero)
  428.             2: lpf_array = $
  429.                   Intarr((arr_x+wide2), (arr_y+wide2), (arr_z+wide2), /Nozero)
  430.             3: lpf_array = $
  431.                   Lonarr((arr_x+wide2), (arr_y+wide2), (arr_z+wide2), /Nozero)
  432.             4: lpf_array = $
  433.                   Fltarr((arr_x+wide2), (arr_y+wide2), (arr_z+wide2), /Nozero)
  434.             5: lpf_array = $
  435.                   Dblarr((arr_x+wide2), (arr_y+wide2), (arr_z+wide2), /Nozero)
  436.             6: lpf_array = $
  437.                   Complexarr((arr_x+wide2), (arr_y+wide2), (arr_z+wide2), $
  438.                      /Nozero)
  439.             7: RETURN, lpf_array
  440.             8: RETURN, lpf_array
  441.          ENDCASE
  442.          wide_x = arr_xm1 + wide
  443.          wide_y = arr_ym1 + wide
  444.          wide_z = arr_zm1 + wide
  445.  
  446.          lpf_array(wide:wide_x, wide:wide_y, wide:wide_z) = array
  447.  
  448.          FOR i=0L, widem1 DO $
  449.             lpf_array(wide:wide_x, wide:wide_y, i) = array(*, *, 0L)
  450.          FOR i=(arr_z+wide), (arr_zm1+wide2) DO $
  451.             lpf_array(wide:wide_x, wide:wide_y, i) = array(*, *, arr_zm1)
  452.  
  453.          FOR i=0L, widem1 DO $
  454.             lpf_array(wide:wide_x, i, *) = lpf_array(wide:wide_x, wide, *)
  455.          FOR i=(arr_y+wide), (arr_ym1+wide2) DO $
  456.             lpf_array(wide:wide_x, i, *) = lpf_array(wide:wide_x, wide_y, *)
  457.  
  458.          FOR i=0L, widem1 DO $
  459.             lpf_array(i, *, *) = lpf_array(wide, *, *)
  460.          FOR i=(arr_x+wide), (arr_xm1+wide2) DO $
  461.             lpf_array(i, *, *) = lpf_array(wide_x, *, *)
  462.  
  463.          ; *** Smooth the "enlarged" array.
  464.          lpf_array = SMOOTH(lpf_array, lpf_band)
  465.  
  466.          ; *** Extract the center of the smoothed array.
  467.          lpf_array = lpf_array(wide:wide_x, wide:wide_y, wide:wide_z)
  468.       ENDIF ELSE BEGIN
  469.          RETURN, array
  470.       ENDELSE
  471.    END
  472.  
  473.    ELSE:
  474. ENDCASE
  475.  
  476. RETURN, lpf_array
  477. END
  478.  
  479.  
  480.  
  481. ;
  482. ;  Purpose:  do the Zooming demo
  483. ;
  484. pro ipr_MakeZooming, $
  485.     drawXSize, $       ; IN: x dimension of drawing area
  486.     drawYSize, $       ; IN: y dimension of drawing area
  487.     pixmapID, $        ; IN: working pixmap
  488.     drawWindowID, $    ; IN: viewing window
  489.     highColor, $       ; IN: maximun index of the color table 
  490.     ZoomStr            ; OUT: structure for zooming (7 items)
  491.  
  492.     LOADCT, 0, /SILENT
  493.     TEK_COLOR, highColor+1, 16
  494.  
  495.     nyc_img = BYTARR(768, 512, /Nozero)
  496.     GET_LUN, data_lun
  497.     OPENR, data_lun, filepath('nyny.dat', $
  498.         SUBDIR=['examples','data'])
  499.     READU, data_lun, nyc_img
  500.     CLOSE, data_lun
  501.     FREE_LUN, data_lun
  502.  
  503.     nyc_img = BYTSCL(nyc_img(0:639, *), TOP=highColor)
  504.     WSET, pixmapID
  505.     Erase, 0
  506.     TV, nyc_img
  507.     WSET, drawWindowID
  508.     Erase
  509.     DEVICE, COPY=[0, 0, drawXSize, drawYSize, 0, 0, pixmapID]
  510.     Empty
  511.  
  512.     win_size = 64
  513.     win_zoom = 192
  514.  
  515.     xpos = 195
  516.     ypos = 185
  517.  
  518.     win_size_h = win_size / 2
  519.     win_zoom_h = win_zoom / 2
  520.  
  521.     xpos = (xpos > win_size_h) < ((drawXSize - win_size_h) - 1)
  522.     ypos = (ypos > win_size_h) < ((drawYSize - win_size_h) - 1)
  523.  
  524.     img_x = xpos - win_zoom_h
  525.     img_y = ypos - win_zoom_h
  526.  
  527.     box_x = [0, win_zoom, win_zoom, 0, 0]
  528.     box_y = [0, 0, win_zoom, win_zoom, 0]
  529.  
  530.     sub_x = xpos - win_size_h
  531.     sub_y = ypos - win_size_h
  532.  
  533.     zoom_img = REBIN(nyc_img((sub_x):(sub_x+win_size-1), $
  534.         (sub_y):(sub_y+win_size-1)), $
  535.         win_zoom, win_zoom)
  536.  
  537.     TV, zoom_img, img_x, img_y
  538.     PLOTS, box_x+img_x, box_y+img_y, $
  539.         /DEVICE, THICK=3, COLOR=highColor+3
  540.     Empty
  541.  
  542.     ZoomStr = { $
  543.         Win_Size_h: win_Size_h, $
  544.         Win_Size: win_Size, $
  545.         Win_Zoom_h: win_Zoom_h, $
  546.         Win_Zoom: win_Zoom, $
  547.         Nyc_img: nyc_img, $
  548.         Box_x: box_x, $
  549.         Box_y: box_y $
  550.     }
  551.  
  552. end      ;  of ipr_MakeZooming
  553.  
  554.  
  555. ;--------------------------------------------------------------------
  556. ;
  557. ;  Purpose:  Create the filter top 2 images(original image, power spectrum)
  558. ;
  559. pro ipr_MakeFilter, $
  560.     drawXSize, $       ; IN: x dimension of drawing area
  561.     drawYSize, $       ; IN: y dimension of drawing area
  562.     highColor, $       ; IN: maximun index of the color table 
  563.     frequencyImage     ; OUT: frequency image (needed by doFilterSlider)
  564.  
  565.     previousFont = !P.FONT
  566.     !P.FONT = 0
  567.  
  568.     tmp_img = BYTARR(768, 512, /Nozero)
  569.     GET_LUN, data_lun
  570.     OPENR, data_lun, filepath('nyny.dat', $
  571.         SUBDIR=['examples','data'])
  572.     READU, data_lun, tmp_img
  573.     o_img = tmp_img[165:228, 150:213]
  574.     CLOSE, data_lun
  575.     FREE_LUN, data_lun
  576.  
  577.     img_x = 256
  578.     img_y = 256
  579.     max_y = drawYSize / 2
  580.     y_text = 8 + !D.Y_Ch_Size
  581.  
  582.     img = BYTSCL(REBIN(o_img, img_x, img_y), TOP=highColor)
  583.  
  584.     if (max_y LT img_y) then begin
  585.        y_diff = (img_y - max_y) / 2
  586.        img = img(*, y_diff:(img_y - (y_diff + 1)))
  587.     endif
  588.  
  589.     img_pos_x = (drawXSize / 2) - img_x
  590.     img_pos_y = (drawYSize / 2)
  591.     Erase, 0
  592.     TV, img, img_pos_x, img_pos_y
  593.  
  594.     XYOUTS, img_pos_x+8, img_pos_y+(max_y-y_text), 'Original Image', $
  595.        COLOR=highColor+2, /Device
  596.     Empty
  597.  
  598.     freq_img = FFT(Temporary(o_img), 1)
  599.     img = REBIN(Shift(BYTSCL(Alog(Abs(freq_img)), TOP=highColor), $
  600.             32, 32), img_x, img_y)
  601.  
  602.     if (max_y LT img_y) then begin
  603.        y_diff = (img_y - max_y) / 2
  604.        img = img(*, y_diff:(img_y - (y_diff + 1)))
  605.     endif
  606.  
  607.     img_pos_x = (drawXSize / 2) + 1
  608.     img_pos_y = (drawYSize / 2)
  609.  
  610.     TV, img, img_pos_x, img_pos_y
  611.     XYOUTS, img_pos_x+8, img_pos_y+(max_y-y_text), 'Power Spectrum', $
  612.        COLOR=highColor+2, /Device
  613.     Empty
  614.  
  615.     filterWidth = 8
  616.     frequencyImage = freq_img
  617.     ipr_DoFilterSlider, drawXSize, drawYSize, highColor, $
  618.          frequencyImage, filterWidth
  619.  
  620.     !P.Font = previousFont
  621. end     ;  of ipr_MakeFilter
  622.  
  623.  
  624. ;--------------------------------------------------------------------
  625. ;
  626. ;  Purpose:  Create the filter bottom 2 images 
  627. ;            (Low pass filter, high pas filter)
  628. ;
  629. pro ipr_DoFilterSlider, $
  630.     drawXSize, $       ; IN: x dimension of drawing area
  631.     drawYSize, $       ; IN: y dimension of drawing area
  632.     highColor, $       ; IN: maximun index of the color table 
  633.     freq_img, $        ; IN: frequency image (needed by doFilterSlider)
  634.     width              ; IN: filter width (slide value)
  635.  
  636.     previousFont = !P.FONT
  637.     !P.FONT = 0
  638.  
  639.     img_x = 256
  640.     img_y = 256
  641.     max_y = drawYSize / 2
  642.     y_text = 8 + !D.Y_Ch_Size
  643.  
  644.     freq = Dist(64)
  645.     filter = 1.0 / (1.0 + (freq / Float(width))^2)
  646.     img = REBIN(BYTSCL(FFT((filter * freq_img), (-1)), TOP=highColor), $
  647.             img_x, img_y)
  648.  
  649.     if (max_y LT img_y) then begin
  650.        y_diff = (img_y - max_y) / 2
  651.        img = img(*, y_diff:(img_y - (y_diff + 1)))
  652.     endif
  653.  
  654.     img_pos_x = (drawXSize / 2) - img_x
  655.     img_pos_y = (drawYSize / 2) - (max_y + 1)
  656.     TV, img, img_pos_x, img_pos_y
  657.  
  658.     XYOUTS, img_pos_x+8, img_pos_y+(max_y-y_text), 'Low Pass Filtered', $
  659.        COLOR=highColor+2, /Device
  660.     Empty
  661.  
  662.     filter = 1.0 - (1.0 / (1.0 + (freq / (2.0 * Float(width)))^2))
  663.     img = REBIN(BYTSCL(FFT((filter * freq_img), (-1)), TOP=highColor), $
  664.             img_x, img_y)
  665.  
  666.     if (max_y LT img_y) then begin
  667.        y_diff = (img_y - max_y) / 2
  668.        img = img(*, y_diff:(img_y - (y_diff + 1)))
  669.     endif
  670.  
  671.     img_pos_x = (drawXSize / 2) + 1
  672.     img_pos_y = (drawYSize / 2) - (max_y + 1)
  673.     TV, img, img_pos_x, img_pos_y
  674.     XYOUTS, img_pos_x+8, img_pos_y+(max_y-y_text), 'High Pass Filtered', $
  675.        COLOR=highColor+2, /Device
  676.     Empty
  677.  
  678.     !P.FONT = previousFont
  679.  
  680. end      ;   of ipr_DoFilterSlider
  681.  
  682. ;--------------------------------------------------------------------
  683. ;
  684. ;  Purpose:  Do the pixel scaling
  685. ;
  686. pro ipr_MakeScaling, $
  687.     drawXSize, $          ; IN: x dimension of drawing area
  688.     drawYSize, $          ; IN: y dimension of drawing area
  689.     highColor, $          ; IN: maximun index of the color table 
  690.     wMinScalingSlider, $  ; IN: minimum scaling slider ID
  691.     wMaxScalingSlider,$   ; IN: maximum scaling slider ID
  692.     ImagePositionX, $     ; OUT: scaled image x position
  693.     ImagePositionY, $     ; OUT: scaled image x position
  694.     scalingImage          ; OUT: scaling image
  695.  
  696.     previousFont = !P.FONT
  697.     !P.FONT = 0
  698.  
  699.     LOADCT, 0, /SILENT
  700.     TEK_COLOR, highColor+1, 16
  701.  
  702.     img = BYTARR(768, 200, /Nozero)
  703.     GET_LUN, data_lun
  704.     OPENR, data_lun, filepath('nyny.dat', $
  705.         SUBDIR=['examples','data'])
  706.     READU, data_lun, img
  707.     CLOSE, data_lun
  708.     FREE_LUN, data_lun
  709.     img = img(0:255, *)
  710.  
  711.     img_pos_x = (drawXSize / 4) - 128
  712.     img_pos_y = (drawYSize / 2) - 100
  713.     Erase, 0
  714.     TV, (img<highColor), img_pos_x, img_pos_y
  715.     XYOUTS, img_pos_x+128, img_pos_y+212, $
  716.         'Original Image', COLOR=highColor+4, /DEVICE, $
  717.         Alignment=0.5
  718.     Empty
  719.  
  720.     img_pos_x = ((3 * drawXSize) / 4) - 128
  721.  
  722.     min_img = MIN(img, MAX=max_img)
  723.     min_val = 115
  724.     max_val = 178
  725.     WIDGET_CONTROL, wMinScalingSlider, $
  726.         SET_VALUE=min_val, SET_SLIDER_MIN=(min_img-2)>0, $
  727.         SET_SLIDER_MAX=(max_img-2)>1
  728.     WIDGET_CONTROL, wMaxScalingSlider,  $
  729.         SET_VALUE=max_val, SET_SLIDER_MIN=(min_img+2)<254, $
  730.         SET_SLIDER_MAX=(max_img+2)<255
  731.  
  732.     img_b = BYTSCL(img, MIN=min_img, MAX=max_img, TOP=highColor)
  733.     TV, img_b, img_pos_x, img_pos_y
  734.     Empty
  735.  
  736.     XYOUTS, img_pos_x+128, img_pos_y+212, $
  737.         'Byte Scaled Image', COLOR=highColor+4, $
  738.         /DEVICE, Alignment=0.5
  739.     Empty
  740.     scalingImage = img
  741.     imagePositionX = img_pos_x
  742.     imagePositionY = img_pos_y
  743.  
  744.     !P.FONT = previousFont
  745. end      ;   of ipr_MakeScaling
  746.  
  747.  
  748. ;--------------------------------------------------------------------
  749. ;
  750. ;  Purpose:  Do the histogram distribution
  751. ;
  752. pro ipr_MakeHistogram, $
  753.     drawXSize, $          ; IN: x dimension of drawing area
  754.     drawYSize, $          ; IN: y dimension of drawing area
  755.     highColor, $          ; IN: maximun index of the color table 
  756.     wMinHistogramSlider, $  ; IN: minimum scaling slider ID
  757.     wMaxHistogramSlider,$   ; IN: maximum scaling slider ID
  758.     ImagePositionX, $     ; OUT: scaled image x position
  759.     ImagePositionY, $     ; OUT: scaled image x position
  760.     scalingImage          ; OUT: scaling image
  761.  
  762.     previousFont = !P.FONT
  763.     !P.FONT = 0
  764.  
  765.     LOADCT, 0, /SILENT
  766.     TEK_COLOR, highColor+1, 16
  767.  
  768.     img = BYTARR(768, 200, /Nozero)
  769.     GET_LUN, data_lun
  770.     OPENR, data_lun, filepath('nyny.dat', $
  771.         SUBDIR=['examples','data'])
  772.     READU, data_lun, img
  773.     CLOSE, data_lun
  774.     FREE_LUN, data_lun
  775.     img = BYTSCL(img(0:255, *), TOP=highColor)
  776.  
  777.     PLOT, Histogram(img), COLOR=highColor+4, $
  778.         TICKLEN=(-0.02), XRANGE=[0, highColor], $
  779.         POSITION=[0.15, 0.6, 0.50, 0.925], $
  780.         BACKGROUND=0, $
  781.         TITLE='Original Histogram', $
  782.         XSTYLE=1
  783.     Empty
  784.  
  785.     img_pos_x = (drawXSize / 2) + 32
  786.     img_pos_y = ((3 * drawYSize) / 4) - 100
  787.     TV, img, img_pos_x, img_pos_y
  788.     Empty
  789.  
  790.     min_img = MIN(img, MAX=max_img)
  791.  
  792.     WIDGET_CONTROL, wMinHistogramSlider, $
  793.         SET_VALUE=min_img, $
  794.         SET_SLIDER_MIN=(min_img-2)>0, $
  795.         SET_SLIDER_MAX=(max_img-2)>1
  796.  
  797.     WIDGET_CONTROL, wMaxHistogramSlider, $
  798.         SET_VALUE=max_img, $
  799.         SET_SLIDER_MIN=(min_img+2)<254, $
  800.         SET_SLIDER_MAX=(max_img+2)<255
  801.  
  802.     scalingImage = img
  803.  
  804.     !P.FONT = previousFont
  805.  
  806.     ipr_DrawHistogram, $ 
  807.         drawXSize, drawYSize, highColor, min_img, max_img, $
  808.         img, imagePositionX, imagePositionY
  809.  
  810. end      ;   of ipr_MakeHistogram
  811.  
  812. ;--------------------------------------------------------------------
  813. ;
  814. ;  Purpose:  Draw the bottomportion of the histogram demo
  815. ;
  816. pro ipr_DrawHistogram, $
  817.     drawXSize, $          ; IN: x dimension of drawing area
  818.     drawYSize, $          ; IN: y dimension of drawing area
  819.     highColor, $          ; IN: maximun index of the color table 
  820.     minValue, $           ; IN: minimum color index value  allowed
  821.     maxValue, $           ; IN: maximum color index value  allowed
  822.     Image, $              ; IN:  image
  823.     ImagePositionX, $     ; OUT: x positon of image
  824.     ImagePositionY        ; OUT: y positon of image
  825.  
  826.     previousFont = !P.FONT
  827.     !P.FONT = 0
  828.  
  829.     img1 = Hist_Equal(image, $
  830.         Minv=minValue, Maxv=maxValue, TOP=highColor)
  831.     POLYFILL, [0.0, 0.5, 0.5, 0.0], [0.0, 0.0, 0.5, 0.5], $
  832.         /Normal, T3D=0, COLOR=0
  833.  
  834.     if (minValue LE 0) then begin
  835.         PLOT, Histogram(Float(img1), MIN=minValue, MAX=maxValue), $
  836.             COLOR=highColor+4, TICKLEN=(-0.02), /NOERASE, $
  837.             POSITION=[0.15, 0.075, 0.50, 0.45], $
  838.             TITLE='Histogram Equalized', $
  839.             BACKGROUND=0, $
  840.             XRANGE=[0, highColor], XSTYLE=1
  841.     endif else begin
  842.         PLOT, [Fltarr(minValue), $
  843.             Histogram(Float(img1), MIN=minValue, MAX=maxValue)], $
  844.             COLOR=highColor+4, TICKLEN=(-0.02), /NOERASE, $
  845.             BACKGROUND=0, $
  846.             POSITION=[0.15, 0.075, 0.50, 0.45], $
  847.             TITLE='Histogram Equalized', XRANGE=[0, highColor], XSTYLE=1
  848.     endelse
  849.     Empty
  850.  
  851.     img_pos_x = (drawXSize / 2) + 32
  852.     img_pos_y = (drawYSize / 4) - 100
  853.     TV, img1, img_pos_x, img_pos_y
  854.     Empty
  855.     imagePositionX = img_pos_x
  856.     imagePositionY = img_pos_y
  857.  
  858.     !P.FONT = previousFont
  859.  
  860. end      ;   of ipr_DrawHistogram
  861.  
  862.  
  863. ;--------------------------------------------------------------------
  864. ;
  865. ;  Purpose:  Do the edge enhancement demo
  866. ;
  867. pro ipr_MakeEdge, $
  868.     drawXSize, $          ; IN: x dimension of drawing area
  869.     drawYSize, $          ; IN: y dimension of drawing area
  870.     highColor, $          ; IN: maximun index of the color table 
  871.     wEdgeSlider, $        ; IN: minimum scaling slider ID
  872.     scalingImage          ; OUT: scaling image
  873.  
  874.     previousFont = !P.FONT
  875.     !P.FONT = 0
  876.  
  877.     LOADCT, 0, /SILENT
  878.     TEK_COLOR, highColor+1, 16
  879.  
  880.     img = BYTARR(768, 200, /Nozero)
  881.     GET_LUN, data_lun
  882.     OPENR, data_lun, filepath('nyny.dat', $
  883.         SUBDIR=['examples','data'])
  884.     READU, data_lun, img
  885.     CLOSE, data_lun
  886.     FREE_LUN, data_lun
  887.  
  888.     img = BYTSCL(img(0:255, *), TOP=highColor)
  889.  
  890.     img_pos_x = (drawXSize / 4) - 128
  891.     img_pos_y = (drawYSize / 2) - 100
  892.     Erase, 0
  893.     TV, img, img_pos_x, img_pos_y
  894.     XYOUTS, img_pos_x+128, img_pos_y+212, $
  895.         'Original Image', COLOR=highColor+4, /DEVICE, $
  896.         Alignment=0.5
  897.     Empty
  898.  
  899.     smoothValue = 0
  900.     WIDGET_CONTROL, wEdgeSlider, SET_VALUE=smoothValue
  901.     ipr_DrawEdge, drawXSize, drawYSize, highColor, $
  902.         smoothValue, img
  903.  
  904.     img_pos_x = ((3 * drawXSize) / 4) - 128
  905.     XYOUTS, img_pos_x+128, img_pos_y+212, $
  906.         'Edge Enhanced Image', COLOR=highColor+4, $
  907.         /DEVICE, Alignment=0.5
  908.     Empty
  909.  
  910.     scalingImage = img
  911.  
  912.     !P.FONT = previousFont
  913.  
  914. end      ;   of ipr_MakeEdge
  915.  
  916. ;--------------------------------------------------------------------
  917. ;
  918. ;  Purpose:  Draw the smoothed edge enhanced image
  919. ;
  920. pro ipr_DrawEdge, $
  921.     drawXSize, $          ; IN: x dimension of drawing area
  922.     drawYSize, $          ; IN: y dimension of drawing area
  923.     highColor, $          ; IN: maximun index of the color table 
  924.     smoothValue, $        ; IN: minimum color index value  allowed
  925.     Image                 ; IN:  image
  926.  
  927.     previousFont = !P.FONT
  928.     !P.FONT = 0
  929.  
  930.     img_pos_x = ((3 * drawXSize) / 4) - 128
  931.     img_pos_y = (drawYSize / 2) - 100
  932.  
  933.     img1 = BYTSCL(SOBEL(LPF_ALL(image, smoothValue)), TOP=highColor)
  934.     TV, img1, img_pos_x, img_pos_y
  935.  
  936.     !P.FONT = previousFont
  937.  
  938. end   ;   of ipr_DrawEdge
  939.  
  940.  
  941. ;--------------------------------------------------------------------
  942. ;
  943. ;  Purpose:  Do the convolution demo
  944. ;
  945. pro ipr_MakeConvolution, $
  946.     drawXSize, $          ; IN: x dimension of drawing area
  947.     drawYSize, $          ; IN: y dimension of drawing area
  948.     highColor, $          ; IN: maximun index of the color table 
  949.     kernel, $             ; OUT: convolution kernel
  950.     scalingImage          ; OUT: scaling image
  951.  
  952.     previousFont = !P.FONT
  953.     !P.FONT = 0
  954.  
  955.     LOADCT, 0, /SILENT
  956.     TEK_COLOR, highColor+1, 16
  957.  
  958.     kernel = BYTARR(10,10)
  959.     img = BYTARR(768, 200, /Nozero)
  960.     GET_LUN, data_lun
  961.     OPENR, data_lun, filepath('nyny.dat', $
  962.         SUBDIR=['examples','data'])
  963.     READU, data_lun, img
  964.     CLOSE, data_lun
  965.     FREE_LUN, data_lun
  966.  
  967.     img = BYTSCL(img(0:255, *), TOP=highColor)
  968.     scalingImage=img
  969.  
  970.     Erase, 0
  971.     ipr_DrawGrid, 3,3, drawXSize, drawYSize, $
  972.          highColor, kernel,  /CELL_COORD
  973.     ipr_DrawGrid, 3,6, drawXSize, drawYSize, $
  974.          highColor, kernel,  /CELL_COORD
  975.     ipr_DrawGrid, 6,3, drawXSize, drawYSize, $
  976.          highColor, kernel,  /CELL_COORD
  977.     ipr_DrawGrid, 6,6, drawXSize, drawYSize, $
  978.          highColor, kernel,  /CELL_COORD
  979.  
  980.     pos_x = (drawXSize / 4)
  981.     img_pos_y = (drawYSize / 2) - 100
  982.  
  983.     XYOUTS, pos_x, img_pos_y+212, 'Kernel', COLOR=highColor+4, /DEVICE, $
  984.         Alignment=0.5
  985.     Empty
  986.  
  987.     ipr_DrawConvolution, drawXSize, drawYSize, $
  988.          highColor, kernel, img
  989.  
  990.     img_pos_x = ((3 * drawXSize) / 4) - 128
  991.     XYOUTS, img_pos_x+128, img_pos_y+212, $
  992.         'Convolved Image', COLOR=highColor+4, $
  993.         /DEVICE, Alignment=0.5
  994.     Empty
  995.  
  996.     !P.FONT = previousFont
  997.  
  998. end   ;   of ipr_MakeConvolution
  999.  
  1000. ;--------------------------------------------------------------------
  1001. ;
  1002. ;  Purpose:  Draw the kernel 
  1003. ;
  1004. pro ipr_DrawGrid, $
  1005.     x, $                    ; x coordinates
  1006.     y, $                    ; y coordinates
  1007.     drawXSize, $            ; IN: x dimension of drawing area
  1008.     drawYSize, $            ; IN: y dimension of drawing area
  1009.     highColor, $            ; IN: maximun index of the color table 
  1010.     kernel, $               ; IN/OUT: convolution kernel
  1011.     Cell_Coord=cell_coord   ; IN: (opt) If x and y are in cell coordinates.
  1012.  
  1013.     grid_pos_x = (drawXSize / 4) - 50
  1014.     grid_pos_y = (drawYSize / 2) - 50
  1015.  
  1016.     if (Keyword_Set(cell_coord)) then begin
  1017.        cell_x = x
  1018.        cell_y = y
  1019.     endif else begin
  1020.        cell_x = Float((x - grid_pos_x) / 10.0)
  1021.        cell_y = Float((y - grid_pos_y) / 10.0)
  1022.        if ((cell_x LT 0.0) OR (cell_y LT 0.0)) then RETURN
  1023.        cell_x = Fix(cell_x)
  1024.        cell_y = Fix(cell_y)
  1025.     ENDelse
  1026.  
  1027.     if ((cell_x GE 10) OR (cell_y GE 10)) then RETURN
  1028.  
  1029.     box_l = (cell_x * 10) + grid_pos_x
  1030.     box_r = box_l + 10
  1031.     box_b = (cell_y * 10) + grid_pos_y
  1032.     box_t = box_b + 10
  1033.  
  1034.     if (kernel(cell_x, cell_y) EQ 1B) then begin
  1035.        cell_color = highColor+1
  1036.        kernel(cell_x, cell_y) = 0B
  1037.     endif else begin
  1038.        cell_color = highColor+2
  1039.        kernel(cell_x, cell_y) = 1B
  1040.     ENDelse
  1041.  
  1042.     POLYFILL, [box_l, box_r, box_r, box_l], $
  1043.         [box_b, box_b, box_t, box_t], $
  1044.         /DEVICE, COLOR=cell_color
  1045.  
  1046.     for i=0, 10 DO begin
  1047.        x = grid_pos_x + (i * 10)
  1048.        y1 = grid_pos_y
  1049.        y2 = grid_pos_y + 100
  1050.        PLOTS, [x, x], [y1, y2], /DEVICE, COLOR=highColor+3
  1051.        x1 = grid_pos_x
  1052.        x2 = grid_pos_x + 100
  1053.        y = grid_pos_y + (i * 10)
  1054.        PLOTS, [x1, x2], [y, y], /DEVICE, COLOR=highColor+3
  1055.     endfor
  1056.  
  1057. end    ;  of ipr_DrawGrid
  1058.  
  1059. ;--------------------------------------------------------------------
  1060. ;
  1061. ;  Purpose:  Draw the convolved image according to the kernel
  1062. ;
  1063. pro ipr_DrawConvolution, $
  1064.     drawXSize, $            ; IN: x dimension of drawing area
  1065.     drawYSize, $            ; IN: y dimension of drawing area
  1066.     highColor, $            ; IN: maximun index of the color table 
  1067.     kernel, $               ; IN: convolution kernel
  1068.     Image                   ; IN: original image to be convolved
  1069.  
  1070.     img_pos_x = ((3 * drawXSize) / 4) - 128
  1071.     img_pos_y = (drawYSize / 2) - 100
  1072.  
  1073.     img1 = CONVOL(Float(image), Float(kernel)/(Total(Float(kernel))>1.0), $
  1074.        /Edge_Truncate, /Center)
  1075.     TV, BYTSCL(img1, TOP=highColor), img_pos_x, img_pos_y
  1076.  
  1077. end    ;  of ipr_DrawConvolution
  1078.  
  1079. ;--------------------------------------------------------------------
  1080. ;
  1081. pro D_Imagproc_Event, sEvent
  1082.  
  1083.     WIDGET_CONTROL, sEvent.id, GET_UVALUE=eventUValue
  1084.  
  1085.     ;  Quit this application using the close box.
  1086.     ;
  1087.     if (TAG_NAMES(sEvent, /STRUCTURE_NAME) EQ $
  1088.         'WIDGET_KILL_REQUEST') then begin
  1089.         WIDGET_CONTROL, sEvent.top, /DESTROY
  1090.         RETURN
  1091.     endif
  1092.     
  1093.     case eventUValue of
  1094.       
  1095.         'DRAWING' : begin
  1096.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1097.             WIDGET_CONTROL, sInfo.wSelectButton, GET_VALUE=index 
  1098.             if (sEvent.type eq 0) then begin    ; button press
  1099.                 case index of
  1100.    
  1101.                     ;  handle the zooming
  1102.                     ;
  1103.                     0 : begin
  1104.  
  1105.                         xpos = (sEvent.x > sInfo.zoomStr.win_size_h) < $
  1106.                             ((sInfo.drawXSize - sInfo.zoomStr.win_size_h) - 1)
  1107.                         ypos = (sEvent.y > sInfo.zoomStr.win_size_h) < $
  1108.                             ((sInfo.drawYSize - sInfo.zoomStr.win_size_h) - 1)
  1109.                         img_x = xpos - sInfo.zoomStr.win_zoom_h
  1110.                         img_y = ypos - sInfo.zoomStr.win_zoom_h
  1111.  
  1112.                         sub_x = xpos - sInfo.zoomStr.win_size_h
  1113.                         sub_y = ypos - sInfo.zoomStr.win_size_h
  1114.  
  1115.                         zoom_img = $
  1116.                             REBIN(sInfo.zoomStr.nyc_img((sub_x): $
  1117.                                 (sub_x+sInfo.zoomStr.win_size-1), $
  1118.                                 (sub_y):(sub_y+sInfo.zoomStr.win_size-1)), $
  1119.                                 sInfo.zoomStr.win_zoom, sInfo.zoomStr.win_zoom)
  1120.                         DEVICE, COPY=[0, 0, sInfo.drawXSize, $
  1121.                             sInfo.drawYSize, 0, 0, sInfo.pixmapArray(0)]
  1122.                         TV, zoom_img, img_x, img_y
  1123.                         PLOTS, sInfo.zoomStr.box_x+img_x, $
  1124.                             sInfo.zoomStr.box_y+img_y, $
  1125.                             /DEVICE, THICK=3, COLOR=sInfo.highColor+3
  1126.                         Empty
  1127.  
  1128.                     end     ;   of 0
  1129.  
  1130.                     ;  Handle the Convolution button press
  1131.                     ;
  1132.                     5 : begin
  1133.  
  1134.                         kernel = sInfo.kernel
  1135.                         ipr_DrawGrid, sEvent.x, sEvent.y, $
  1136.                             sInfo.drawXSize, sInfo.drawYSize, $
  1137.                             sInfo.highColor, kernel
  1138.                         sInfo.kernel = kernel
  1139.                     end    ;   of  5
  1140.  
  1141.                 endcase
  1142.             endif
  1143.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1144.         end     ;  of  DRAWING
  1145.  
  1146.         'SELECT' : begin
  1147.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1148.             WSET, sInfo.drawWindowID
  1149.             case sEvent.value of
  1150.  
  1151.                 ;  Zooming
  1152.                 ;
  1153.                 0 : begin
  1154.                     WIDGET_CONTROL, sInfo.currentBase, MAP=0
  1155.                     WIDGET_CONTROL, sInfo.wSelectionBase(0), MAP=1
  1156.                     sInfo.currentBase = sInfo.wSelectionBase(0)
  1157.                     WIDGET_CONTROL, sInfo.wAreaDraw, DRAW_BUTTON_EVENTS=1
  1158.                     WSET, sInfo.drawWindowID
  1159.                     ERASE
  1160.                     ipr_MakeZooming, sInfo.drawXSize, sInfo.drawYSize, $
  1161.                         sInfo.pixmapArray(0), sInfo.drawWindowID, $
  1162.                         sInfo.highColor, sInfo.zoomStr
  1163.  
  1164.                     textChange = ['zoom', 'position']
  1165.                     putTips, sInfo.sText, sInfo.wText[1], $
  1166.                         textChange, [1,2]
  1167.  
  1168.                 end  ;  of 0
  1169.  
  1170.                 ;  Fourier filtering
  1171.                 ;
  1172.                 1 : begin
  1173.                     WIDGET_CONTROL, sInfo.currentBase, MAP=0
  1174.                     WIDGET_CONTROL, sInfo.wSelectionBase(1), MAP=1
  1175.                     sInfo.currentBase = sInfo.wSelectionBase(1)
  1176.                     WSET, sInfo.drawWindowID
  1177.                     ERASE
  1178.                     filterWidth = 8
  1179.                     frequencyImage = COMPLEXARR(64,64)
  1180.                     WIDGET_CONTROL, sInfo.wFilterSlider, SET_VALUE=filterWidth
  1181.                     ipr_MakeFilter, sInfo.drawXSize, sInfo.drawYSize, $
  1182.                         sInfo.highColor, frequencyImage
  1183.                     sInfo.frequencyImage = frequencyImage
  1184.                     WIDGET_CONTROL, sInfo.wAreaDraw, DRAW_BUTTON_EVENTS=0
  1185.  
  1186.                     textChange = ['width1', 'width2']
  1187.                     putTips, sInfo.sText, sInfo.wText[1], $
  1188.                         textChange, [1,2]
  1189.                 end   ; of 1
  1190.  
  1191.                 ;  Pixel scaling
  1192.                 ;
  1193.                 2 : begin
  1194.                     WIDGET_CONTROL, sInfo.currentBase, MAP=0
  1195.                     WIDGET_CONTROL, sInfo.wSelectionBase(2), MAP=1
  1196.                     sInfo.currentBase = sInfo.wSelectionBase(2)
  1197.                     imagePositionX = 0
  1198.                     imagePositionY = 0
  1199.                     ipr_MakeScaling, sInfo.drawXSize, sInfo.drawYSize, $
  1200.                         sInfo.highColor, $
  1201.                         sInfo.wMinScalingSlider, sInfo.wMaxScalingSlider, $
  1202.                         imagePositionX, imagePositionY, scalingImage
  1203.                     sInfo.scalingImage = scalingImage
  1204.                     sInfo.imagePositionX = imagePositionX
  1205.                     sInfo.imagePositionY = imagePositionY
  1206.                     scalingImage = 0
  1207.                     WIDGET_CONTROL, sInfo.wAreaDraw, DRAW_BUTTON_EVENTS=0
  1208.  
  1209.                     textChange = ['byte1', 'byte2']
  1210.                     putTips, sInfo.sText, sInfo.wText[1], $
  1211.                         textChange, [1,2]
  1212.                 end   ;  of 2
  1213.  
  1214.                 ;  Histogram of pixel values distribution
  1215.                 ;
  1216.                 3 : begin
  1217.                     WIDGET_CONTROL, sInfo.currentBase, MAP=0
  1218.                     WIDGET_CONTROL, sInfo.wSelectionBase(3), MAP=1
  1219.                     sInfo.currentBase = sInfo.wSelectionBase(3)
  1220.                     WSET, sInfo.drawWindowID
  1221.                     ERASE
  1222.                     imagePositionX = 0
  1223.                     imagePositionY = 0
  1224.                     ipr_MakeHistogram, sInfo.drawXSize, sInfo.drawYSize, $
  1225.                         sInfo.highColor, $
  1226.                         sInfo.wMinHistogramSlider, sInfo.wMaxHistogramSlider, $
  1227.                         imagePositionX, imagePositionY, scalingImage
  1228.                     sInfo.scalingImage = scalingImage
  1229.                     sInfo.imagePositionX = imagePositionX
  1230.                     sInfo.imagePositionY = imagePositionY
  1231.                     scalingImage = 0
  1232.                     WIDGET_CONTROL, sInfo.wAreaDraw, DRAW_BUTTON_EVENTS=0
  1233.                     textChange = ['byte1', 'byte2']
  1234.                     putTips, sInfo.sText, sInfo.wText[1], $
  1235.                         textChange, [1,2]
  1236.                 end    ;  of 3
  1237.  
  1238.                 ;  Edge enhancement
  1239.                 ;
  1240.                 4 : begin
  1241.                     WIDGET_CONTROL, sInfo.currentBase, MAP=0
  1242.                     WIDGET_CONTROL, sInfo.wSelectionBase(4), MAP=1
  1243.                     sInfo.currentBase = sInfo.wSelectionBase(4)
  1244.                     WIDGET_CONTROL, sInfo.wEdgeSlider, SET_VALUE=0
  1245.                     smoothValue = 0
  1246.                     WSET, sInfo.drawWindowID
  1247.                     ERASE
  1248.                     ipr_MakeEdge , sInfo.drawXSize, sInfo.drawYSize, $
  1249.                         sInfo.highColor, $
  1250.                         sInfo.wEdgeSlider, $
  1251.                         scalingImage
  1252.                     sInfo.scalingImage = scalingImage
  1253.                     scalingImage = 0
  1254.                     WIDGET_CONTROL, sInfo.wAreaDraw, DRAW_BUTTON_EVENTS=0
  1255.                     textChange = ['smooth1', 'smooth2']
  1256.                     putTips, sInfo.sText, sInfo.wText[1], $
  1257.                         textChange, [1,2]
  1258.                 end    ;  of 4
  1259.  
  1260.                 ;  Convolution
  1261.                 ;
  1262.                 5 : begin
  1263.                     WIDGET_CONTROL, sInfo.currentBase, MAP=0
  1264.                     WIDGET_CONTROL, sInfo.wSelectionBase(5), MAP=1
  1265.                     WIDGET_CONTROL, sInfo.wTopBase, SENSITIVE=0
  1266.                     sInfo.currentBase = sInfo.wSelectionBase(5)
  1267.                     WSET, sInfo.drawWindowID
  1268.                     ERASE
  1269.                     ipr_MakeConvolution , sInfo.drawXSize, sInfo.drawYSize, $
  1270.                         sInfo.highColor, $
  1271.                         kernel, $
  1272.                         scalingImage
  1273.                     sInfo.scalingImage = scalingImage
  1274.                     sInfo.Kernel = kernel
  1275.                     scalingImage = 0
  1276.                     WIDGET_CONTROL, sInfo.wTopBase, SENSITIVE=1
  1277.                     textChange = ['conv1', 'conv2']
  1278.                     putTips, sInfo.sText, sInfo.wText[1], $
  1279.                         textChange, [1,2]
  1280.                     WIDGET_CONTROL, sInfo.wAreaDraw, DRAW_BUTTON_EVENTS=1
  1281.                 end    ;  of 5
  1282.                     
  1283.             endcase
  1284.             
  1285.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1286.         end   ;                      of   SELECT  
  1287.         
  1288.         'FILTERWIDTH' : begin
  1289.  
  1290.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1291.             WIDGET_CONTROL, sInfo.wFilterSlider, GET_VALUE=filterWidth
  1292.             WSET, sInfo.drawWindowID
  1293.             ipr_DoFilterSlider, sInfo.drawXSize, sInfo.drawYSize, $
  1294.                 sInfo.highColor, sInfo.frequencyImage, filterWidth
  1295.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1296.         end    ;       of  ABOVE
  1297.  
  1298.  
  1299.         'MINSCALING' : begin
  1300.  
  1301.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1302.             WIDGET_CONTROL, sInfo.wMinScalingSlider, GET_VALUE=minValue
  1303.             WIDGET_CONTROL, sInfo.wMaxScalingSlider, GET_VALUE=maxValue
  1304.             if (maxValue LE minValue) then begin
  1305.                 maxValue = minValue + 1
  1306.                 WIDGET_CONTROL, sInfo.wMaxScalingSlider, SET_VALUE=maxValue
  1307.             endif
  1308.             scaledImage = BYTSCL(sInfo.scalingImage, $
  1309.                  MIN=minValue, MAX=maxValue, TOP=sInfo.highColor)
  1310.             TV, scaledImage, sInfo.imagePositionX, sInfo.imagePositionY
  1311.             Empty
  1312.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1313.         end    ;       of  MINSCALING
  1314.  
  1315.  
  1316.         'MAXSCALING' : begin
  1317.  
  1318.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1319.             WIDGET_CONTROL, sInfo.wMinScalingSlider, GET_VALUE=minValue
  1320.             WIDGET_CONTROL, sInfo.wMaxScalingSlider, GET_VALUE=maxValue
  1321.             if (minValue GE maxValue) then begin
  1322.                 minValue = maxValue - 1
  1323.                 WIDGET_CONTROL, sInfo.wMinScalingSlider, SET_VALUE=minValue
  1324.             endif
  1325.             scaledImage = BYTSCL(sInfo.scalingImage, $
  1326.                  MIN=minValue, MAX=maxValue, TOP=sInfo.highColor)
  1327.             TV, scaledImage, sInfo.imagePositionX, sInfo.imagePositionY
  1328.             Empty
  1329.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1330.         end    ;       of  MAXSCALING
  1331.  
  1332.  
  1333.         'MINHISTOGRAM' : begin
  1334.  
  1335.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1336.             WIDGET_CONTROL, sInfo.wMinHistogramSlider, GET_VALUE=minValue
  1337.             WIDGET_CONTROL, sInfo.wMaxHistogramSlider, GET_VALUE=maxValue
  1338.             if (maxValue LE minValue) then begin
  1339.                 maxValue = minValue + 1
  1340.                 WIDGET_CONTROL, sInfo.wMaxHistogramSlider, SET_VALUE=maxValue
  1341.             endif
  1342.             ipr_DrawHistogram, $ 
  1343.                 sInfo.drawXSize, sInfo.drawYSize, sInfo.highColor, $
  1344.                 minValue, maxValue, $
  1345.                 sInfo.ScalingImage, sInfo.imagePositionX, sInfo.imagePositionY
  1346.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1347.         end    ;       of  MINHISTOGRAM
  1348.  
  1349.  
  1350.         'MAXHISTOGRAM' : begin
  1351.  
  1352.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1353.             WIDGET_CONTROL, sInfo.wMinHistogramSlider, GET_VALUE=minValue
  1354.             WIDGET_CONTROL, sInfo.wMaxHistogramSlider, GET_VALUE=maxValue
  1355.             if (minValue GE maxValue) then begin
  1356.                 minValue = maxValue - 1
  1357.                 WIDGET_CONTROL, sInfo.wMinHistogramSlider, SET_VALUE=minValue
  1358.             endif
  1359.             ipr_DrawHistogram, $ 
  1360.                 sInfo.drawXSize, sInfo.drawYSize, sInfo.highColor, $
  1361.                 minValue, maxValue, $
  1362.                 sInfo.ScalingImage, sInfo.imagePositionX, sInfo.imagePositionY
  1363.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1364.         end    ;       of  MAXHISTOGRAM
  1365.  
  1366.  
  1367.         'EDGE' : begin
  1368.  
  1369.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1370.             WIDGET_CONTROL, sInfo.wEdgeSlider, GET_VALUE=smoothValue
  1371.             ipr_DrawEdge, $ 
  1372.                 sInfo.drawXSize, sInfo.drawYSize, sInfo.highColor, $
  1373.                 smoothValue, sInfo.ScalingImage
  1374.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1375.         end    ;       of  MAXHISTOGRAM
  1376.  
  1377.         'CONVOLUTION' : begin
  1378.  
  1379.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=sInfo, /NO_COPY
  1380.             WIDGET_CONTROL, sInfo.wTopBase, SENSITIVE=0
  1381.             ipr_DrawConvolution, sInfo.drawXSize, sInfo.drawYSize, $
  1382.                 sInfo.highColor, sInfo.kernel, sInfo.scalingImage
  1383.             WIDGET_CONTROL, sInfo.wTopBase, SENSITIVE=1
  1384.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=sInfo, /NO_COPY
  1385.         end    ;       of  CONVOLUTION 
  1386.  
  1387.  
  1388.         'QUIT' : begin
  1389.  
  1390.             WIDGET_CONTROL, sEvent.top, /DESTROY
  1391.         end
  1392.  
  1393.         'ABOUT' : begin
  1394.             if( Xregistered('XDisplayFile') ne 0) then RETURN
  1395.             XDisplayFile, filepath("imagproc.txt", $
  1396.                 SUBDIR=['examples','demo','demotext']), $
  1397.                 DONE_BUTTON='Done', $
  1398.                 TITLE="About image processing", $
  1399.                 GROUP=sEvent.top, WIDTH=55, HEIGHT=14
  1400.         end           ;  of ABOUT
  1401.          
  1402.         else :   ;  do nothing
  1403.         
  1404.     endcase
  1405. end
  1406.  
  1407. ;--------------------------------------------------------------------
  1408. ;
  1409. pro D_ImagprocCleanup, wTopBase
  1410.  
  1411.     ;  Get the color table saved in the window's user value
  1412.     ;
  1413.     WIDGET_CONTROL, wTopBase, GET_UVALUE=sInfo, /NO_COPY
  1414.    
  1415.     ;  Restore the previous color table.
  1416.     ;
  1417.     TVLCT, sInfo.colorTable
  1418.  
  1419.     ;  Restore the previous plot font.
  1420.     ;
  1421.     !P.FONT = sInfo.plotFont
  1422.     
  1423.     !P.CHARSIZE = sInfo.previousChar
  1424.  
  1425.     ;  Delete the pixmap windows.
  1426.     ;
  1427.     for i = 0, sInfo.nPixmap-1 do begin
  1428.         WDELETE, sInfo.pixmapArray(i)
  1429.     endfor
  1430.     ;  Map the group leader base if it exists.
  1431.     ;
  1432.     if (WIDGET_INFO(sInfo.groupBase, /VALID_ID)) then $
  1433.         WIDGET_CONTROL, sInfo.groupBase, /MAP
  1434.  
  1435. end   ; of D_ImagprocCleanup
  1436.  
  1437. ;--------------------------------------------------------------------
  1438. ;
  1439. ;   PURPOSE 
  1440. ;
  1441. pro D_Imagproc, $
  1442.     GROUP=group, $     ; IN: (opt) group identifier
  1443.     APPTLB = appTLB    ; OUT: (opt) TLB of this application
  1444.  
  1445.     ; Check the validity of the group identifier
  1446.     ;
  1447.     ngroup = N_ELEMENTS(group)
  1448.     if (ngroup NE 0) then begin
  1449.         check = WIDGET_INFO(group, /VALID_ID)
  1450.         if (check NE 1) then begin
  1451.             print,'Error, the group identifier is not valid'
  1452.             print, 'Return to the main application'
  1453.             RETURN
  1454.         endif
  1455.         groupBase = group
  1456.     endif else groupBase = 0L
  1457.  
  1458.     ;  Get the current color table. It will be restored when exiting.
  1459.     ;
  1460.     TVLCT, savedR, savedG, savedB, /GET
  1461.     colorTable = [[savedR],[savedG],[savedB]]
  1462.  
  1463.     ;  Also save the font
  1464.     ;
  1465.     plotFont = !P.FONT
  1466.  
  1467.     ;  Get the screen size.
  1468.     ;
  1469.     DEVICE, GET_SCREEN_SIZE = screenSize
  1470.  
  1471.     if (ngroup EQ 0) then begin
  1472.         drawbase = startmes()
  1473.      endif else begin
  1474.         drawbase = startmes(GROUP=group)
  1475.     endelse
  1476.  
  1477.     previousChar = !P.CHARSIZE
  1478.  
  1479.     !P.CHARSIZE = 8.0 / !D.X_CH_SIZE
  1480.  
  1481.     ; Get the character scaling factor
  1482.     ;
  1483.     charscale = 8.0/!d.X_CH_SIZE
  1484.  
  1485.     ;  Load a new color table
  1486.     ;
  1487.     LOADCT, 12, /SILENT
  1488.     highColor = !D.TABLE_SIZE-18
  1489.     TEK_COLOR, highColor+1, 16
  1490.  
  1491.     ;  Use hardware-drawn font.
  1492.     ;
  1493.     !P.FONT=0
  1494.  
  1495.     ;  Set up the drawing area size (predetermined for image processing)
  1496.     ;
  1497.     drawXSize = 512
  1498.     drawYSize = 400
  1499.  
  1500.     if (screenSize[0] LT 800) then begin
  1501.         widID = $
  1502.         DIALOG_MESSAGE('This application is optimized' + $
  1503.             ' for 800 x 640 resolution.', $
  1504.             /INforMATION)
  1505.     endif
  1506.  
  1507.     ;  Get the tips.
  1508.     ;
  1509.     sText = getTips(filepath('imagproc.tip', $
  1510.         SUBDIR=['examples','demo', 'demotext']) )
  1511.  
  1512.     ;  Set the slider width on windows
  1513.     ;
  1514.     sliderWidth = 70
  1515.  
  1516.     ;  Add scroll bar if the monitor x size is less than 750 pixels.
  1517.     ;
  1518.     if (screenSize(0) LT 750) then myScroll=1 else myScroll=0
  1519.  
  1520.     ;  Create the widgets.
  1521.     ;
  1522.     if (myScroll EQ 1) then begin
  1523.         if (N_ELEMENTS(group) EQ 0) then begin
  1524.             wTopBase = WIDGET_BASE(TITLE="Image Processing/ New-York City", $
  1525.                 /COLUMN, $
  1526.                 /TLB_KILL_REQUEST_EVENTS, $
  1527.                 SCROLL=myScroll, $
  1528.                 X_SCROLL_SIZE=screenSize[0]-75, $
  1529.                 Y_SCROLL_SIZE=screenSize[1]-75, $
  1530.                 MAP=0, $
  1531.                 TLB_FRAME_ATTR=1, MBAR=barBase)
  1532.         endif else begin
  1533.             wTopBase = WIDGET_BASE(TITLE="Image Processing/ New-York City", $
  1534.                 /COLUMN, $
  1535.                 /TLB_KILL_REQUEST_EVENTS, $
  1536.                 SCROLL=myScroll, $
  1537.                 X_SCROLL_SIZE=screenSize[0]-75, $
  1538.                 Y_SCROLL_SIZE=screenSize[1]-75, $
  1539.                 MAP=0, $
  1540.                 GROUP_LEADER=group, $
  1541.                 TLB_FRAME_ATTR=1, MBAR=barBase)
  1542.         endelse
  1543.     endif else begin
  1544.         if (N_ELEMENTS(group) EQ 0) then begin
  1545.             wTopBase = WIDGET_BASE(TITLE="Image Processing/ New-York City", $
  1546.                 /COLUMN, $
  1547.                 /TLB_KILL_REQUEST_EVENTS, $
  1548.                 MAP=0, $
  1549.                 TLB_FRAME_ATTR=1, MBAR=barBase)
  1550.         endif else begin
  1551.             wTopBase = WIDGET_BASE(TITLE="Image Processing/ New-York City", $
  1552.                 /COLUMN, $
  1553.                 /TLB_KILL_REQUEST_EVENTS, $
  1554.                 MAP=0, $
  1555.                 GROUP_LEADER=group, $
  1556.                 TLB_FRAME_ATTR=1, MBAR=barBase)
  1557.         endelse
  1558.     endelse
  1559.  
  1560.         ;  Create the menu bar items
  1561.         ;
  1562.         wFileButton = WIDGET_BUTTON(barBase, VALUE='File')
  1563.           
  1564.             wQuitButton = WIDGET_BUTTON(wFileButton, VALUE='Quit', $
  1565.                 UVALUE='QUIT')
  1566.                 
  1567.         wHelpButton = WIDGET_BUTTON(barBase, VALUE='About', /HELP)
  1568.           
  1569.             wAboutButton = WIDGET_BUTTON(wHelpButton, $
  1570.                 VALUE='About Image Processing', $
  1571.                 UVALUE='ABOUT')
  1572.                 
  1573.         ;  Create the left and right bases
  1574.         ;
  1575.         wTopRowBase = WIDGET_BASE(wTopBase, COLUMN=2)
  1576.         
  1577.             wLeftBase = WIDGET_BASE(wTopRowBase, /COLUMN)
  1578.             
  1579.                 wSelectButton = CW_BGROUP(wLeftBase, $
  1580.                     ['Zooming',    'Fourier Filter', $
  1581.                     'Pixel Scaling',    'Histogram', $
  1582.                     'Edges', 'Convolution'], $
  1583.                     UVALUE='SELECT', /NO_RELEASE, /EXCLUSIVE)
  1584.  
  1585.                 ;  Create a base for each options 
  1586.                 ;
  1587.                 wSelectionBase = LONARR(6)   ; 6 is the number of selections
  1588.                 wTempBase = WIDGET_BASE(wLeftbase)
  1589.  
  1590.                     ;  Put the selection bases into the temporary (temp)
  1591.                     ;  base. This way, the selection bases overlaps each
  1592.                     ;  another. When the user select from wSelectButton,
  1593.                     ;  only one selection base is mapped.
  1594.                     ;
  1595.                     for i=0, N_ELEMENTS(wSelectionbase)-1 do  begin
  1596.                         wSelectionbase(i) = WIDGET_BASE(wTempBase, $
  1597.                         UVALUE=0L, /COLUMN, MAP=0, YPAD=20)
  1598.                     endfor
  1599.  
  1600.                         ;  Create the content of each selection base
  1601.                         ;  Beginning with zooming
  1602.                         ;
  1603.                         wZoomingBase = WIDGET_BASE(wSelectionBase(0), $
  1604.                             /COLUMN, /BASE_ALIGN_CENTER)  
  1605.  
  1606.                         ;  Fourier filtering.
  1607.                         ;
  1608.                         wFilterBase = WIDGET_BASE(wSelectionBase(1), $
  1609.                             /COLUMN, /FRAME)  
  1610.  
  1611.                             if (!D.Name EQ 'WIN') then begin
  1612.                                 wFilterSlider = WIDGET_SLIDER(wFilterBase, $
  1613.                                     MINIMUM=1, MAXIMUM=20, $
  1614.                                     XSIZE=sliderWidth, $
  1615.                                     VALUE=8, $
  1616.                                     TITLE='Filter Width', UVALUE='FILTERWIDTH')
  1617.                             endif else begin
  1618.                                 wFilterSlider = WIDGET_SLIDER(wFilterBase, $
  1619.                                     MINIMUM=1, MAXIMUM=20, $
  1620.                                     VALUE=8, $
  1621.                                     TITLE='Filter Width', UVALUE='FILTERWIDTH')
  1622.                             endelse
  1623.                         
  1624.                         ;  Pixel scaling.
  1625.                         ;
  1626.                         wScalingBase = WIDGET_BASE(wSelectionBase(2), $
  1627.                             /COLUMN, /FRAME)  
  1628.  
  1629.                             if (!D.Name EQ 'WIN') then begin
  1630.                                 wMinScalingSlider = $
  1631.                                     WIDGET_SLIDER(wScalingBase, $
  1632.                                     MINIMUM=89, MAXIMUM=253, $
  1633.                                     XSIZE=sliderWidth, $
  1634.                                     VALUE=115, $
  1635.                                     TITLE='Minimum', UVALUE='MINSCALING')
  1636.  
  1637.                                 wMaxScalingSlider =WIDGET_SLIDER(wScalingBase, $
  1638.                                     MINIMUM=93, MAXIMUM=255, $
  1639.                                     XSIZE=sliderWidth, $
  1640.                                     VALUE=178, $
  1641.                                     TITLE='Maximum', UVALUE='MAXSCALING')
  1642.                             endif else begin
  1643.                                 wMinScalingSlider = $
  1644.                                     WIDGET_SLIDER(wScalingBase, $
  1645.                                     MINIMUM=89, MAXIMUM=253, $
  1646.                                     VALUE=115, $
  1647.                                     TITLE='Minimum', UVALUE='MINSCALING')
  1648.  
  1649.                                 wMaxScalingSlider =WIDGET_SLIDER(wScalingBase, $
  1650.                                     MINIMUM=93, MAXIMUM=255, $
  1651.                                     VALUE=178, $
  1652.                                     TITLE='Maximum', UVALUE='MAXSCALING')
  1653.                             endelse
  1654.  
  1655.                         ;  Histogram distribution
  1656.                         ;
  1657.                         wHistogramBase = WIDGET_BASE(wSelectionBase(3), $
  1658.                             /COLUMN, /FRAME)  
  1659.  
  1660.                             if (!D.Name EQ 'WIN') then begin
  1661.                                 wMinHistogramSlider = $
  1662.                                     WIDGET_SLIDER(wHistogramBase, $
  1663.                                     XSIZE=sliderWidth, $
  1664.                                     MINIMUM=0, MAXIMUM=220, $
  1665.                                     VALUE=0, $
  1666.                                     TITLE='Minimum', UVALUE='MINHISTOGRAM')
  1667.  
  1668.                                 wMaxHistogramSlider = $
  1669.                                     WIDGET_SLIDER(wHistogramBase, $
  1670.                                     XSIZE=sliderWidth, $
  1671.                                     MINIMUM=2, MAXIMUM=224, $
  1672.                                     VALUE=222, $
  1673.                                     TITLE='Maximum', UVALUE='MAXHISTOGRAM')
  1674.                             endif else begin
  1675.                                 wMinHistogramSlider = $
  1676.                                     WIDGET_SLIDER(wHistogramBase, $
  1677.                                     MINIMUM=0, MAXIMUM=220, $
  1678.                                     VALUE=0, $
  1679.                                     TITLE='Minimum', UVALUE='MINHISTOGRAM')
  1680.  
  1681.                                 wMaxHistogramSlider = $
  1682.                                     WIDGET_SLIDER(wHistogramBase, $
  1683.                                     MINIMUM=2, MAXIMUM=224, $
  1684.                                     VALUE=222, $
  1685.                                     TITLE='Maximum', UVALUE='MAXHISTOGRAM')
  1686.                             endelse
  1687.  
  1688.                         ;  Edge enhancement
  1689.                         ;
  1690.                         wEdgeBase = WIDGET_BASE(wSelectionBase(4), $
  1691.                             /COLUMN, /FRAME)
  1692.  
  1693.                             if (!D.Name EQ 'WIN') then begin
  1694.                                 wEdgeSlider = WIDGET_SLIDER(wEdgeBase, $
  1695.                                     MINIMUM=0, MAXIMUM=20, $
  1696.                                     XSIZE=sliderWidth, $
  1697.                                     VALUE=0, $
  1698.                                     TITLE='Smooth width', UVALUE='EDGE')
  1699.                             endif else begin
  1700.                                 wEdgeSlider = WIDGET_SLIDER(wEdgeBase, $
  1701.                                     MINIMUM=0, MAXIMUM=20, $
  1702.                                     VALUE=0, $
  1703.                                     TITLE='Smooth Width', UVALUE='EDGE')
  1704.                             endelse
  1705.     
  1706.                         ;  Convolution
  1707.                         ;
  1708.                         wConvolutionBase = WIDGET_BASE(wSelectionBase(5), $
  1709.                             /COLUMN, /FRAME)
  1710.  
  1711.                             wConvolutionButton = $
  1712.                                 WIDGET_Button(wConvolutionBase, $
  1713.                                 VALUE='Convolve', UVALUE='CONVOLUTION')
  1714.                 
  1715.             wRightBase = WIDGET_BASE(wTopRowBase, /COLUMN)
  1716.             
  1717.                 wAreaDraw = WIDGET_DRAW(wRightBase, XSIZE=drawXSize, $
  1718.                     YSIZE=drawYSize, RETAIN=2, UVALUE='DRAWING')
  1719.  
  1720.         ;  Create tips texts.
  1721.         ;
  1722.         wStatusBase = WIDGET_BASE(wTopBase, MAP=0, /ROW)
  1723.  
  1724.             nWidgets = 2
  1725.             wText = LONARR(nWidgets)
  1726.             widTips, wStatusBase, sText.text, XSIZE=36, $
  1727.                 YSIZE=3, NWIDGETS=nWidgets, wText
  1728.  
  1729.     ;  Realize the widget hierarchy.
  1730.     ;
  1731.     WIDGET_CONTROL, wTopBase, /REALIZE
  1732.  
  1733.     ;  Returns the top level base in the appTLB keyword.
  1734.     ;
  1735.     appTLB = wTopBase
  1736.  
  1737.     ;  Size the tips widgets.
  1738.     ;
  1739.     sizeTips, wTopBase, wText, wStatusBase
  1740.  
  1741.     WIDGET_CONTROL, wSelectButton, SET_VALUE=0
  1742.     
  1743.     ; Determine the window value of plot window
  1744.     ;
  1745.     WIDGET_CONTROL, wAreaDraw, GET_VALUE=drawWindowID
  1746.  
  1747.     ;  Map the integration demo (index 0) as default
  1748.     ;
  1749.     WIDGET_CONTROL, wSelectionBase(0), MAP=1
  1750.  
  1751.     ;  Create the pixmaps
  1752.     ;
  1753.     nPixmap = 1
  1754.     pixmapArray = LONARR(nPixmap)
  1755.     for i = 0, nPixmap-1 do begin
  1756.         Window, /FREE, XSIZE=drawXSize, YSIZE=drawYSize, /PIXMAP
  1757.         pixmapArray(i) = !D.Window
  1758.     endfor
  1759.      
  1760.     ;  Make the zooming demo as default.
  1761.     ;
  1762.     WSET, drawWindowID
  1763.     ERASE
  1764.     ipr_MakeZooming, drawXSize, drawYSize, $
  1765.         pixmapArray(0), drawWindowID, highColor, $
  1766.         zoomStr
  1767.     WIDGET_CONTROL, wAreaDraw, /DRAW_BUTTON_EVENTS
  1768.     
  1769.  
  1770.     ;  Create the info structure
  1771.     ;
  1772.     sInfo = { $
  1773.         ZoomStr: zoomStr, $                          ; Zoom structure
  1774.         FrequencyImage: COMPLEXARR(64,64,/NOZERO), $ ; Image frequencies
  1775.         ScalingImage: BYTARR(256,200,/NOZERO), $     ; Scaled image
  1776.         Kernel: BYTARR(10,10), $                     ; Kernel array
  1777.         ImagePositionX: 0, $                         ; Position of zoomed image
  1778.         ImagePositionY: 0, $
  1779.         HighColor: highColor, $                      ; Highest color index
  1780.         NPixmap: nPixmap, $                          ; Number of pixmaps
  1781.         PixmapArray: pixmapArray, $                  ; Pixmap IDs array
  1782.         DrawXSize: drawXSize, $                      ; Drawing area size
  1783.         DrawYSize: drawYSize, $
  1784.         CurrentBase : wSelectionBase(0), $           ; Current displayed base
  1785.         ColorTable:colorTable, $                     ; Color table to restore
  1786.         CharScale: charScale, $                      ; Character scaling factor
  1787.         DrawWindowID: drawWindowID, $                ; Window ID
  1788.         WTopBase: wTopBase, $                        ; Top level base ID
  1789.         WSelectionBase: wSelectionBase, $            ; Selection base IDs
  1790.         WSelectButton: wSelectButton, $              ; Buttons and sliders IDs
  1791.         WConvolutionButton: wConvolutionButton, $
  1792.         WFilterSlider: wFilterSlider, $
  1793.         WMinScalingSlider: wMinScalingSlider, $
  1794.         WMaxScalingSlider: wMaxScalingSlider, $
  1795.         WMinHistogramSlider: wMinHistogramSlider, $
  1796.         WMaxHistogramSlider: wMaxHistogramSlider, $
  1797.         WEdgeSlider: wEdgeSlider, $
  1798.         WAreaDraw: wAreaDraw, $                      ; Widget draw ID
  1799.         WText: wText, $                              ; Widget text IDs for tips.
  1800.         SText: sText, $                              ; Text structure for tips.
  1801.         previousChar : previousChar, $               ; Previous character size
  1802.         plotFont: plotFont, $                        ; Font to trestore
  1803.         groupBase: groupBase $                       ; Base of Group Leader
  1804.     }
  1805.     
  1806.     ;  Register the info structure in the user value
  1807.     ;  of the top-level base.
  1808.     ;
  1809.     WIDGET_CONTROL, wTopBase, SET_UVALUE=sInfo, /NO_COPY
  1810.  
  1811.     ;  Destroy the starting up window.
  1812.     ;
  1813.     WIDGET_CONTROL, drawbase, /DESTROY
  1814.  
  1815.     ;  Map the top level base.
  1816.     ;
  1817.     WIDGET_CONTROL, wTopBase, MAP=1
  1818.      
  1819.     ; Register with the BIG GUY, XMANAGER!
  1820.     ;
  1821.     XMANAGER, "D_Imagproc", wTopBase, $
  1822.         EVENT_HANDLER="D_Imagproc_Event", $
  1823.         CLEANUP="D_ImagprocCleanup", /NO_BLOCK
  1824.     
  1825. end   ; of D_Imagproc
  1826.